#include <sw/redis++/redis++.h>
#include <iostream>
#include <string>
#include <vector>

using namespace sw::redis;

void RetryConnection(Redis &redis)
{
    std::string s1 = redis.ping();
    int cnt = 5;
    while (s1 != "PONG" && cnt)
    {
        --cnt;
        s1 = redis.ping();
    }
}

void unity1(Redis &redis)
{
    printf("开始执行zadd和zcard命令了\n");
    redis.flushall();
    long long ret = redis.zadd("z1", "hello", 10);
    std::cout << "单个数据zadd : " << ret << std::endl;

    // 批量zadd
    redis.flushall();
    // 使用vector，类型为pair<double,std::string>
    std::vector<std::pair<std::string, double>> inputs = {{"m1", 10}, {"m2", 20}, {"m3", 30}};

    ret = redis.zadd("z1", inputs.begin(), inputs.end());
    std::cout << "批量zadd : " << ret << std::endl;
    std::cout << "-------------------------" << std::endl;

    ret = redis.zcard("z1");
    std::cout << "集合中元素个数为: " << ret << std::endl;
}

void unity2(Redis &redis)
{
    printf("开始测试zcount和zrange了\n");
    redis.flushall();
    std::vector<std::pair<std::string, double>> inputs = {{"m1", 10}, {"m2", 20}, {"m3", 30}};
    long long ret = redis.zadd("z1", inputs.begin(), inputs.end());
    std::cout << "批量zadd : " << ret << std::endl;
    std::cout << "-------------------------" << std::endl;
    // BoundType参数可以设置：开区间，闭区间，左开右闭，左闭右开
    sw::redis::BoundedInterval<double> bound(10.0, 20.0, BoundType::CLOSED);
    ret = redis.zcount("z1", bound);
    std::cout << "zcount: " << ret << std::endl;
    std::cout << "---------------------------" << std::endl;
    std::vector<std::string> res;
    auto it = std::back_inserter(res);
    redis.zrange("z1", 0, 2, it);
    for (auto &s : res)
    {
        std::cout << s << std::endl;
    }
}

void unity3(Redis &redis)
{
    printf("开始测试zrevrange和Zrangebyscore了\n");
    redis.flushall();
    std::vector<std::pair<std::string, double>> inputs = {{"m1", 10}, {"m2", 20}, {"m3", 5}};
    long long ret = redis.zadd("z1", inputs.begin(), inputs.end());
    std::cout << "批量zadd : " << ret << std::endl;
    std::cout << "-------------------------" << std::endl;

    std::vector<std::string> res;
    auto it = std::back_inserter(res);
    redis.zrevrange("z1", 0, 2, it);
    for (auto &s : res)
    {
        std::cout << s << std::endl;
    }
    res.clear();
    it = std::back_inserter(res);
    std::cout << "--------------------" << std::endl;
    BoundedInterval<double> bound(10.0, 15.0, BoundType::CLOSED);

    redis.zrangebyscore("z1", bound, it);
    for (auto &s : res)
    {
        std::cout << s << std::endl;
    }
}

void unity4(Redis &redis)
{
    printf("开始执行zrem命令\n");
    redis.flushall();
    std::vector<std::pair<std::string, double>> inputs = {{"m1", 10}, {"m2", 20}, {"m3", 5}};
    long long ret = redis.zadd("z1", inputs.begin(), inputs.end());
    std::cout << "批量zadd : " << ret << std::endl;
    std::cout << "-------------------------" << std::endl;
    ret = redis.zrem("z1", "m1");
    std::cout << "zrem : " << ret << std::endl;
    ret = redis.zrem("z1", "m2");
    std::cout << "zrem : " << ret << std::endl;
    ret = redis.zrem("z1", "m3");
    std::cout << "zrem : " << ret << std::endl;
    // 删除一个不存在的值
    ret = redis.zrem("z1", "m4");
    std::cout << "zrem : " << ret << std::endl;
}
int main()
{
    Redis redis("tcp://127.0.0.1:6379");
    RetryConnection(redis);

    // unity1(redis);
    // unity2(redis);
    // unity3(redis);
    // unity4(redis);
    return 0;
}